// Package utils
// @Author: zhangdi
// @File: events
// @Version: 1.0.0
// @Date: 2023/5/22 16:04
package event

import (
	"sync"
	"time"
)

// EventSystem 事件系统类
type EventSystem struct {
	listeners map[string][]EventListener
	mutex     sync.Mutex
}

func NewEventSystem() *EventSystem {
	return &EventSystem{
		listeners: make(map[string][]EventListener),
	}
}

// AddEventListener 注册事件监听器，一个name可以添加多个事件，name和event属于一对多的关系
func (es *EventSystem) AddEventListener(name string, listener EventListener) {
	es.mutex.Lock()
	defer es.mutex.Unlock()

	if _, ok := es.listeners[name]; !ok {
		es.listeners[name] = []EventListener{}
	}
	es.listeners[name] = append(es.listeners[name], listener)
}

// RemoveEventListener 移除事件监听器
func (es *EventSystem) RemoveEventListener(eventName string, listener EventListener) {
	es.mutex.Lock()
	defer es.mutex.Unlock()

	if _, ok := es.listeners[eventName]; ok {
		for i, l := range es.listeners[eventName] {
			if l == listener {
				es.listeners[eventName] = append(es.listeners[eventName][0:i], es.listeners[eventName][i+1:]...)
				return
			}
		}
	}
}

// TriggerEvent 触发事件
func (es *EventSystem) TriggerEvent(eventName string, data any) {
	es.mutex.Lock()
	defer es.mutex.Unlock()

	e := Event{
		Name: eventName,
		Data: data,
		Time: time.Now(),
		ID:   time.Now().Unix(), //当前时间戳
	}

	if listeners, ok := es.listeners[e.Name]; ok {
		for _, l := range listeners {
			l.HandleEvent(&e)
		}
	}
}
